import * as THREE from 'three'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js' // 控制器
import Stats from 'three/addons/libs/stats.module.js' // 渲染帧率
const scene = new THREE.Scene() // 场景

// geometry  [dʒiˈɑːmətri]  几何体
const geometry = new THREE.BoxGeometry(50, 50, 50) // 长方体
// const geometry = new THREE.SphereGeometry(30) // 球体
// const geometry = new THREE.CylinderGeometry(20, 30, 100) // 圆柱体 上面半径 ，下面半径 ，高度
// const geometry = new THREE.PlaneGeometry(50, 25)// 平面 长方形 宽，高
// const geometry = new THREE.CircleGeometry(20) // 圆形平面 半径

// material  [məˈtɪəriəl] 材质  
// 1. 不受光照的材质, MeshBasicMaterial 
// 2. 受光照的材质： MeshLambertMaterial ...
// 3. 高光网格材质： MeshPhongMaterial
const material = new THREE.MeshPhongMaterial({
  color: 0xff00000,
  shininess: 20,// 高光部分亮度，默认30
  side: THREE.DoubleSide, // 矩形平面，圆形平面 两面可见，不设置则只有一面可见 ,不会影响立体图形
  specular: 0x444444 //高光部分的强度，
})

// mesh 网格;  mesh是场景的属性
const mesh = new THREE.Mesh(geometry, material)
mesh.position.set(0, 0, 0)
scene.add(mesh)

// 创建x轴的网格阵列
// for (let i = 1; i < 11; i++) {
//   for (let j = 1; j < 11; j++) {
//     const mesh = new THREE.Mesh(geometry, material)
//     mesh.position.set(i * 100, 0, j * 100)
//     scene.add(mesh)
//   }
// }


// for (let i = 0; i < 2000; i++) { // 物体的个数越多 ，渲染帧率越低，跟电脑相关 
//   const geometry = new THREE.BoxGeometry(10, 10, 10)
//   const mesh = new THREE.Mesh(geometry, material)
//   let x = (Math.random() - 0.5) * 200
//   let y = (Math.random() - 0.5) * 200
//   let z = (Math.random() - 0.5) * 200
//   mesh.position.set(x, y, z)
//   scene.add(mesh)
// }

// 创建坐标轴
const axesHelper = new THREE.AxesHelper(350)
scene.add(axesHelper)

//光源是场景的属性 //点光远，环境光源，平行光源，聚光灯光源
const spotLight = new THREE.SpotLight(0xffffff, 1.0)
spotLight.decay = 0.0
spotLight.position.set(200, 150, 100)
// scene.add(spotLight)

// 环境光场景  -- 环境光没有可视化
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5)
scene.add(ambientLight)

// 点光源可视化
const pointLightHelper = new THREE.PointLightHelper(spotLight, 10)
// scene.add(pointLightHelper)

// 平行光场景
const directionLight = new THREE.DirectionalLight(0xffffff, 1.0)
directionLight.position.set(50, 100, 80)
scene.add(directionLight)
//平行光光源可视化
const directionLightHelper = new THREE.DirectionalLightHelper(directionLight, 10, 0xffff00)
scene.add(directionLightHelper)

//定义相机输出画布的尺寸
// const width = 500
// const height = 300

const width = window.innerWidth
const height = window.innerHeight

// 设置透视投影相机 --- 模拟人的眼睛的特效 ， 远小近大
let fov = 30
// let fov = 60
const camera = new THREE.PerspectiveCamera(fov, width / height, 0.1, 3000)  // 角度，宽高比，近裁截面，远裁截面
camera.position.set(300, 300, 300)
// camera.position.set(2000, 2000, 2000)
camera.lookAt(0, 0, 0) // 改变相机的观察目标点  
// camera.lookAt(800, 0, 800)  // 注意，相机控件 OrbitControls 会影响LookAt设置注意手动设置OrbitControls的参数

// 渲染器
const renderer = new THREE.WebGLRenderer({
  antialias: true // 启用抗锯齿
})
renderer.setSize(width, height) // canvas 画布的大小
// renderer.render(scene, camera) //渲染 生成了一个canvas对象
document.body.appendChild(renderer.domElement) //添加到页面上

renderer.setPixelRatio(window.devicePixelRatio) // 告诉renderer 屏幕的设备像素比
renderer.setClearColor(0x777777) // 背景的颜色
// 渲染帧率的可视化  默认左上角 可改
const stats = new Stats()
stats.setMode(1) // 显示模式  0，帧率  1.渲染间隔
document.body.appendChild(stats.domElement)

// 循环渲染 大约秒渲染60次
const clock = new THREE.Clock()
function render() {
  stats.update()
  let setp = clock.getDelta() * 1000 // 两次之间的时间间隔
  let zhenlv = 1000 / setp // 渲染帧率
  // mesh.rotateY(0.01) // 网格对象环绕Y轴旋转 角度为0.01 ,每秒钟转动约60次
  renderer.render(scene, camera) // scene,camera 是渲染器的属性
  window.requestAnimationFrame(render)
}
render()

// 轨道控制器
const controls = new OrbitControls(camera, renderer.domElement)
controls.target.set(100, 0, 100) // 注意 camera的lookAt 改变这里需要设置成一样的值
controls.update() // 注意 camera的lookAt 要加上这句代码
controls.addEventListener('change', function () {
  // renderer.render(scene, camera)
})

// window.onresize // 调整窗口大小的时候触发
window.onresize = function () {
  let width = window.innerWidth
  let height = window.innerHeight
  renderer.setSize(width, height) // 重新设置canvas的大小
  camera.aspect = width / height  // 设定相机的宽高比
  camera.updateProjectionMatrix() // 更新相机的投影矩阵
}